import { Cartesian3, PostProcessStage } from 'cesium';
import { isNil } from 'lodash';
import { useEffect } from 'react';
import { useCesium } from 'resium';
import { useAppSelector } from '../../../../store';
import { CesiumMath } from '../../../../utils/Type';

// 雨
const FS_Rain = `uniform sampler2D colorTexture;
			 in vec2 v_textureCoordinates;
       uniform float tiltAngle;
       uniform float rainSize;
       uniform float rainWidth;
       uniform float rainSpeed;
			 float hash(float x){
					return fract(sin(x*233.3)*13.13);
			 }
       out vec4 vFragColor;
			void main(void){
				float time = czm_frameNumber / rainSpeed;
			  vec2 resolution = czm_viewport.zw;
			  vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);
			  vec3 c=vec3(1.0,1.0,1.0);
			  float a= tiltAngle;
			  float si=sin(a),co=cos(a);
			  uv*=mat2(co,-si,si,co);
			  uv*=length(uv+vec2(0,4.9))*rainSize + 1.;
			  float v = 1.0 - abs(sin(hash(floor(uv.x * rainWidth)) * 2.0));
			  float b=clamp(abs(sin(20.*time*v+uv.y*(5./(2.+v))))-.95,0.,1.)*20.;
			  c*=v*b;
        vFragColor = mix(texture(colorTexture, v_textureCoordinates), vec4(c,.3), .3);
			}
`;

export default function Demo() {
    const { viewer } = useCesium();
    const pos = useAppSelector((state) => state.scene.initPosition);

    useEffect(() => {
        if (isNil(viewer)) return;
        let lastStage: PostProcessStage | null = null;

        // 移除
        const removeStage = () => {
            lastStage && viewer.scene.postProcessStages.remove(lastStage);
            lastStage = null;
        };

        // 添加雨
        const handleRain = (rainWidth, rainSpeed) => {
            removeStage();
            const rain = new PostProcessStage({
                name: 'hi_rain',
                fragmentShader: FS_Rain,
                uniforms: {
                    tiltAngle: 0.3, // 倾斜角度
                    rainSize: 0.8, // 雨大小
                    rainWidth, // 雨宽度
                    rainSpeed, // 雨速
                },
            });
            viewer.scene.postProcessStages.add(rain);
            lastStage = rain;
        };

        handleRain(30.0, 90.0); // 调用方式

        const target = Cartesian3.fromDegrees(pos.longitude, pos.latitude, 1000);
        viewer.camera.setView({
            destination: target,
            orientation: {
                heading: viewer.camera.heading,
                pitch: CesiumMath.toDegrees(0),
                roll: viewer.camera.roll,
                up: Cartesian3.clone(Cartesian3.UNIT_Y),
            },
        });

        return () => {
            removeStage();
        };
    }, [pos, viewer]);

    return null;
}
